﻿using System;
using System.Text;
using System.Web;
using System.Web.Mvc;
using CWB.Common.Constant;
using CWB.Common.Exceptions;
using CWB.Web.CacheLayer;
using CWB.Web.Configuration;
using CWB.Web.Models.Configuration;
using CWB.Web.MVC.ActionResults;
using CWB.Web.MVC.ReturnResult;
using log4net;

namespace CWB.Web.MVC.BaseController
{
    public class MultiCultureBaseController : Controller
    {
        static readonly ILog log = LogManager.GetLogger(typeof(MultiCultureBaseController).Name);

        protected Permission ControllerPermision { get; set; }
        protected LanguageInfo LanguageInfo { get; private set; }
        protected SessionData sessionData = new SessionData();

        protected MultiCultureBaseController(LanguageInfo languageInfo)
        {
            if (languageInfo == null)
            {
                throw new ArgumentNullException("LanguageInfo is Null");
            }
            LanguageInfo = languageInfo;
        }
        protected override void OnException(ExceptionContext filterContext)
        {
            if (filterContext.Exception.GetType() == typeof(NoPermissionException))
            {
                RejectRequestResult.RejectRequest(filterContext, RejectReason.PermissionDeny, sessionData);
            }
            else
            {
                filterContext.Result = Json(new RejectResult(RejectReason.ServerError, "#"), JsonRequestBehavior.AllowGet);
                filterContext.ExceptionHandled = true;
                log.Error(string.Format("OnException =>{0} {1}", filterContext.RequestContext.HttpContext.Request.Url, filterContext.ExceptionHandled), filterContext.Exception);
            }
            //base.OnException(filterContext);
        }

        protected override void OnResultExecuting(ResultExecutingContext filterContext)
        {
            base.OnResultExecuting(filterContext);
            //add P3P header to make sure the pages inside other frames able to use cookies
            filterContext.HttpContext.Response.AddHeader("p3p", "CP=\"CAO PSA OUR\"");
        }

        protected override void HandleUnknownAction(string actionName)
        {
            throw new HttpException(404, "");
        }

        protected override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            filterContext.HttpContext.Response.Cache.SetOmitVaryStar(true);
            ViewData["_cul"] = LanguageInfo.CultureName;
            ViewData["_v"] = AppConfigManager.SystemSetting.StaticFileVersionNumber;
            ViewData["_pg"] = AppConfigManager.SystemSetting.UsersPageingSize;

            if (sessionData != null && sessionData.trading != null)
            {
                ViewData["_displayname"] = sessionData.trading.userName;
            }

            //OutputCacheExpiryHelper.AddDependency(filterContext.HttpContext);

            base.OnActionExecuting(filterContext);
        }

        protected override void OnAuthorization(AuthorizationContext filterContext)
        {
            if (ControllerPermision != Permission.Public)
            {
                if (sessionData.trading!= null)
                {
                    bool isSessionExpired = true;
                    if (sessionData.trading.isLogined)
                    {
                        //check session id
                        LoginType lt = (LoginType)sessionData.trading.loginType;

                        switch (lt)
                        {
                            case LoginType.Member:
                                break;
                            case LoginType.Agent:
                                isSessionExpired = AgentCache.isExpired(sessionData.trading);
                                break;
                            case LoginType.Bo:
                                isSessionExpired = BouCache.isExpired(sessionData.trading);
                                break;
                            default:
                                log.Debug(string.Format("Can't found the LogingType[{0}]", Enum.GetName(typeof(LoginType), lt)));
                                break;
                        }
                        if (isSessionExpired)
                        {
                            log.Debug("System kickout");
                            RejectRequestResult.RejectRequest(filterContext, RejectReason.SsoKickOut, sessionData);
                        }
                    }
                    else
                    {
                        log.Debug("Session Lost");
                        RejectRequestResult.RejectRequest(filterContext, RejectReason.SessionLost, sessionData);
                    }
                }
                else
                {
                    log.Debug("Session Lost");
                    RejectRequestResult.RejectRequest(filterContext, RejectReason.SessionLost, sessionData);
                }
            }
        }

        protected override JsonResult Json(object data, string contentType, Encoding contentEncoding, JsonRequestBehavior behavior)
        {
            return new JsonDataContractResult
            {
                Data = data,
                ContentType = contentType,
                ContentEncoding = contentEncoding,
                JsonRequestBehavior = behavior
            };
        }

        public RedirectToRouteResult CultureRedirectToAction(string culture, string controllerName, string actionName)
        {
            return base.RedirectToAction(actionName, controllerName, new { Culture = culture });
        }

        public RedirectToRouteResult CultureRedirectToAction(string actionName)
        {
            return CultureRedirectToAction(LanguageInfo.CultureName, actionName);
        }

        public RedirectToRouteResult CultureRedirectToAction(string controllerName, string actionName)
        {
            return CultureRedirectToAction(LanguageInfo.CultureName, controllerName, actionName);
        }
    }
}
